#pragma once

#include "PNGFinder.h"
#include "FiringEvent.h"
#include "Connection.h"
#include "GroupLink.h"

using namespace System;

namespace SpikingNeuronLib
{
	// The functions in this class are derived from the work of Eugene Izhikevich (see http://www.izhikevich.org/publications/spnet.htm)
	// The newer activity-triggered (slow, but more precise) algorithm is implemented here (see PNGFinderEstimationAlgorithm.h for the original algorithm)
	// Some of the implementation details have been substantially changed to enable interfacing with multiple network types
	public ref class PNGFinderSimulationAlgorithm :
		public PNGFinder
	{
	private:
		PNGFinderSimulationAlgorithm() {}

	protected:
		array<double>^ _a;
		array<double>^ _d;

		array<VirtualEvent, 2>^ _virtualEvents;

		int SearchCurrentTripletSimulated(String^ tag, int anchorNeuron, array<int>^ triplet, int maxDelay, int numPolychronousGroups,
			int groupSize, double weightLimit, int maxPNGLength, int numExcitatoryNeurons, int totalNeurons,
			Dictionary<Tuple<int, int>^, Connection^>^ connectionPairDictionary,
			Dictionary<int, Dictionary<int, List<Connection^>^>^>^ groupedConnectionDictionary,
			array<int>^ numPostspikes, array<FiringEvent>^ groupEvents, array<VirtualEvent, 2>^ virtualEvents,
			List<LinkedEventPair^>^ links, array<double>^ a, array<double>^ d, int verboseLevel);

	public:
		PNGFinderSimulationAlgorithm(List<Connection^>^ connections, int numExcitatoryNeurons, int totalNeurons, int groupSize, int maxPNGLength);
		~PNGFinderSimulationAlgorithm() {}

		int SearchCurrentTriplet(String^ tag, int anchorNeuron, array<int>^ triplet, int maxDelay, int numPolychronousGroups,
			int groupSize, double weightLimit, int maxPNGLength, int numExcitatoryNeurons, int totalNeurons,
			Dictionary<Tuple<int, int>^, Connection^>^ connectionPairDictionary,
			Dictionary<int, Dictionary<int, List<Connection^>^>^>^ groupedConnectionDictionary, int verboseLevel) override;
	};
}
